package com.blog.aspect;

import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.apache.ibatis.binding.MapperMethod;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author 任浩
 * @version 1.0
 *
 * 统一日志记录。
 */

@Component
@Slf4j
@Aspect
public class unifiedIog {
    /**
     * 设置切入点表达式
     * 这里设置的切入点表达式，表示对controller的所有方法进行增强。
     *
     * execution 基于方法签名的切点定义,就是匹配方法名
     * annotation基于注解的切点定义,括号里面的值就是注解的具体路径。
     */
    @Pointcut("execution(* com.blog.service.*.*(..))")
    public void pointcut(){

    }

    /**
     * 这是为所有的service方法使用aop增强，增加一个通知。
     * @param joinPoint
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){  //JoinPoint是得到要增强的对象。
        //得到增强方法的对象。
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //首要要得到httpservletRequest
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        if(requestAttributes == null){
            return;
        }
        HttpServletRequest request = requestAttributes.getRequest();

        //通过request得到当前访问用户的id地址。
        String ip = request.getRemoteHost();
        //得到当前的时间。
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        String dateTime = LocalDateTime.now().format(dateTimeFormatter);
        //获得当前增强方法的名字
        String declaringTypeName = methodSignature.getDeclaringTypeName();

        log.info("用户[{}] 在{}时间，访问了{}",ip,dateTime,declaringTypeName);
    }
}
